A string of letters A, B,
C is forbidden
if there are three consecutive letters from which one is A, one is B and one is
C. For example, BAACAACCBAAA is forbidden, while AABBCCAABB is not.
How many such strings of
length n are not forbidden?
Input. Each line contains one number n (1 ≤ n ≤
30).
Output. For each input value of n
print in a separate line the number of strings of length n are not forbidden.
Sample
input |
Sample
output |
2 3 4 |
9 21 51 |
SOLUTION
recurrent relation
Algorithm analysis
Let rep[i] contains the number of not forbidden
strings of length i, which two last
letters are equal. Let nonrep[i] contains
the number of not forbidden strings of length i, which two last letters are different. The answer to the problem
is the value rep[n] + nonrep[n].
Let us calculate the
values of the cells directly:
Computing the rep[i]. The i - th letter must be exactly the same as the letter at the (i – 1) - th place.
rep[i] = rep[i – 1] + nonrep[i – 1]
Computing the nonrep[i]. If the (i – 1) - th and (i –
2) - th letters are the same, we can
place to the i - th position any of
two letters that do not coincide with it. It the (i – 1) - th and (i –
2) - th letters are different, the (i – 1) - th letter to the i - th position can’t be duplicated, we
can’t put to the i – th position the
letter different from (i – 1) - th and
(i – 2) - th (it is forbidden to put three
consecutive letters in a row). Therefore in this case to the i – th position we must place the (i – 2) - th letter.
nonrep[i] = 2 * rep[i – 1] +
nonrep[i – 1]
For example, the cells of
the rep and nonrep arrays will contain the following values:
If we denote by rep(n) and nonrep(n) the functions that compute the number of not forbidden strings
of length n, respectively, with
repeated last two letters and not repeated, then we can write the recurrence
relation:
,
The answer is rep(n) + nonrep(n).
Algorithm realization
Declare the global arrays.
long long rep[31], nonrep[31];
Fill the cells of rep and nonrep arrays according to the formulas
given above.
long long countNotForbidden(int
n)
{
int i;
rep[1]
= 0; rep[2] = 3;
nonrep[1] = 3; nonrep[2] = 6;
for(i = 3; i <= n; i++)
{
rep[i] = rep[i-1] + nonrep[i-1];
nonrep[i] = 2 * rep[i-1] + nonrep[i-1];
}
return rep[n] + nonrep[n];
}
The main part of the program.
while(scanf("%d",&n) == 1)
{
res =
countNotForbidden(n);
printf("%lld\n",res);
}
Algorithm realization – recursion with memorization
#include <stdio.h>
#include <string.h>
int n;
long long repMem[31], nonrepMem[31];
long long nonrep(int n);
long long rep(int n)
{
if (n == 1) return 0;
if (n == 2) return 3;
if (repMem[n] != -1) return
repMem[n];
return repMem[n] = rep(n - 1) + nonrep(n - 1);
}
long long nonrep(int n)
{
if (n == 1) return 3;
if (n == 2) return 6;
if (nonrepMem[n] != -1) return
nonrepMem[n];
return nonrepMem[n] = 2 * rep(n - 1) + nonrep(n - 1);
}
int main(void)
{
memset(repMem,-1,sizeof(repMem));
memset(nonrepMem,-1,sizeof(nonrepMem));
while(scanf("%d",&n)
== 1)
printf("%lld\n",rep(n) +
nonrep(n));
return 0;
}
Java realization
import java.util.*;
public class
{
static int MAX = 31;
static long rep[] = new long[MAX], nonrep[] = new long[MAX];
static long countNotForbidden(int n)
{
rep[1] = 0; rep[2] = 3;
nonrep[1] = 3; nonrep[2] = 6;
for(int i = 3; i <= n; i++)
{
rep[i] = rep[i-1] + nonrep[i-1];
nonrep[i] = 2 * rep[i-1] + nonrep[i-1];
}
return rep[n] + nonrep[n];
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
while(con.hasNextInt())
{
int n = con.nextInt();
long res = countNotForbidden(n);
System.out.println(res);
}
}
}
Java realization – recursion with
memorization
import java.util.*;
public class
{
static long repMem[] = new long[31];
static long nonrepMem[] = new long[31];
static long rep(int n)
{
if (n == 1) return 0;
if (n == 2) return 3;
if (repMem[n] != -1) return repMem[n];
return repMem[n] = rep(n - 1) + nonrep(n - 1);
}
static long nonrep(int n)
{
if (n == 1) return 3;
if (n == 2) return 6;
if (nonrepMem[n] != -1) return nonrepMem[n];
return nonrepMem[n] = 2 * rep(n - 1) + nonrep(n - 1);
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
Arrays.fill(repMem, -1);
Arrays.fill(nonrepMem, -1);
while(con.hasNext())
{
int n = con.nextInt();
System.out.println(rep(n) + nonrep(n));
}
con.close();
}
}